﻿using System;
using Agro.Models;
using SN.Data;
using System.Linq;
using System.Collections.Generic;

namespace Agro.Services
{
    public class RoleService : BaseService, IRoleService
    {
        public bool SaveRole(Models.T_Role role, out string msg)
        {
            msg = string.Empty;
            if (role.Role_ID > 0)
            {
                //判断是否已经存在
                if (DB.Exists<T_Role>(T_Role._.Role_Code == role.Role_Code &&
                                                        T_Role._.Role_ID != role.Role_ID))
                {
                    msg = "角色代码已经存在";
                    return false;
                }

                role.Attach();
            }
            else
            {
                if (DB.Exists<T_Role>(T_Role._.Role_Code == role.Role_Code))
                {
                    msg = "角色代码已经存在";
                    return false;
                }
                role.Detach(); //新增
            }
            //保存
            DB.Save<T_Role>(role);
            return true;
        }

        public bool DeleteRoles(string ids, out string msg)
        {
            msg = string.Empty;
            if (DB.Exists<T_User_Role>(T_User_Role._.UR_RoleID.In(ids.Split(','))))
            {
                msg = "角色已在角色权限表中使用!";
                return false;
            }
            //可以删除
            DB.Delete<T_Role>(T_Role._.Role_ID.In(ids.Split(',')));
            return true;
        }

        public System.Data.DataTable GetRoleUsers(SN.Core.QueryBase query,string id,int CurrUserOrganization_ID)
        {
            //Field[] fields = { 
            //                   T_User_Role._.All,
            //                   T_User._.User_Code,
            //                   T_User._.User_ID,
            //                   T_User._.User_Name,
            //                   T_Role._.Role_ID,
            //                   T_Role._.Role_Name,
            //                   T_Organization._.Organization_Name
            //                 };
            //var section = DB.From<T_User_Role>()
            //    .InnerJoin<T_Role>(T_Role._.Role_ID == T_User_Role._.UR_RoleID)
            //    .InnerJoin<T_User>(T_User._.User_ID == T_User_Role._.UR_UserID)
            //    .LeftJoin<T_Organization>(T_User._.User_OrganizationID == T_Organization._.Organization_ID)
            //    .Where(where);

            string sql= @"select T_User.User_ID,T_User.User_Code,T_User.User_Name,T_Role.Role_ID,T_Role.Role_Name,T_Organization.Organization_Name from
                            T_User_Role,T_Role,T_User left join T_Organization on(T_User.User_OrganizationID=T_Organization.Organization_ID)
                            where T_Role.Role_ID = T_User_Role.UR_RoleID and 
                                  T_User.User_ID = T_User_Role.UR_UserID and 
                                  T_User_Role.UR_RoleID = {0} and 
                                  T_Organization.Organization_ID in ( Select Organization_ID From GetChildrenOrg({1}))";
            System.Data.DataTable dt = GetPageData(string.Format(sql,id,CurrUserOrganization_ID),query);
                //FromSql(string.Format(sql, id, CurrUserOrganization_ID)).ToDataTable().;
            return dt;
        }

        public System.Data.DataTable GetUserNotInRole(SN.Core.QueryBase query,string id, int CurrUserOrganization_ID)
        {
            //Field[] fields = { 
            //                   T_User_Role._.All,
            //                   T_User._.User_Code,
            //                   T_User._.User_ID,
            //                   T_User._.User_Name,
            //                   T_Role._.Role_ID,
            //                   T_Role._.Role_Name,
            //                   T_Organization._.Organization_Name
            //                 };
            //var section = DB.From<T_User_Role>()
            //    .InnerJoin<T_Role>(T_Role._.Role_ID == T_User_Role._.UR_RoleID)
            //    .InnerJoin<T_User>(T_User._.User_ID == T_User_Role._.UR_UserID)
            //    .LeftJoin<T_Organization>(T_User._.User_OrganizationID == T_Organization._.Organization_ID)
            //    .Where(where);

            string sql = @"select T_User.User_ID,T_User.User_Code,T_User.User_Name,T_Organization.Organization_Name from
                            T_User left join T_Organization on(T_User.User_OrganizationID=T_Organization.Organization_ID)
                            where T_User.User_ID not in (select UR_UserID from T_User_Role where UR_RoleID={0}) and 
                                  T_Organization.Organization_ID in ( Select Organization_ID From GetChildrenOrg({1}))";
            System.Data.DataTable dt = GetPageData(string.Format(sql, id, CurrUserOrganization_ID),query);
            return dt;
        }

        public string SaveRoleMenus(int roleId, string menuIds)
        {
            string Msg = string.Empty;
            using (DbTrans trans = DB.BeginTrans())
            {
                try
                {
                    trans.Delete<T_Role_Permission>(T_Role_Permission._.RP_RoleID == roleId);
                    string[] menuIdArray = menuIds.Split(',');
                    DbBatch batch = trans.BeginBatch(menuIdArray.Length);
                    foreach (var menuId in menuIdArray)
                    {
                        if (string.IsNullOrEmpty(menuId)) continue;
                        T_Role_Permission roleMenu = new T_Role_Permission();
                        roleMenu.RP_Type = "T_Menu";
                        roleMenu.RP_TableID = menuId;
                        roleMenu.RP_RoleID = roleId;
                        roleMenu.RP_IsLook = "1";
                        roleMenu.Detach();
                        batch.Save(roleMenu);
                    }
                    batch.Process();
                    trans.Commit();
                }
                catch (Exception ex)
                {
                    trans.Rollback();
                    Msg = ex.Message;
                }
            }
            return Msg;
        }

        public string SaveRoleUsers(string roleId, string userIds)
        {
            string Msg = string.Empty;
            using (DbTrans trans = DB.BeginTrans())
            {
                try
                {
                    //trans.Delete<T_User_Role>(T_Role_Permission._.RP_RoleID == roleId);
                    string[] userIdArray = userIds.Split(',');
                    DbBatch batch = trans.BeginBatch(userIdArray.Length);
                    foreach (var userId in userIdArray)
                    {
                        if (string.IsNullOrEmpty(userId)) continue;
                        //先删再保存
                        trans.Delete<T_User_Role>(T_User_Role._.UR_RoleID == Convert.ToInt32(roleId) && T_User_Role._.UR_UserID == Convert.ToInt32(userId));

                        T_User_Role userRole = new T_User_Role();

                        userRole.UR_RoleID = Convert.ToInt32(roleId);
                        userRole.UR_UserID = Convert.ToInt32(userId);
                        //
                        userRole.UR_Status = "1";
                        userRole.UR_CreateDate = DateTime.Now.ToString("yyyyMMdd");
                        batch.Save(userRole);
                    }
                    batch.Process();
                    trans.Commit();
                }
                catch (Exception ex)
                {
                    trans.Rollback();
                    Msg = ex.Message;
                }
            }
            return Msg;
        }

        public IList<T_Role> GetUserRoleList(int userId)
        {
            return DB.From<T_Role>().LeftJoin<T_User_Role>(T_User_Role._.UR_RoleID == T_Role._.Role_ID)
                .Where(T_User_Role._.UR_UserID == userId && T_Role._.Role_IsAvailable == 1).ToList();
        }


        public string RemoveRoleUser(string roleId, string UserId)
        {
            string Msg = string.Empty;
            using (DbTrans trans = DB.BeginTrans())
            {
                try
                {
                    //开始删除该角色 - 用户
                    int icount = trans.Delete<T_User_Role>(T_User_Role._.UR_RoleID == roleId && T_User_Role._.UR_UserID == UserId);
                    if (icount == 1)
                    {
                        trans.Commit();
                    }
                    else
                    {
                        throw new Exception("用户角色表里删除该数据记录不唯一!");
                    }
                }
                catch (Exception ex)
                {
                    Msg = ex.Message;
                    trans.Rollback();
                    throw;
                }

            }
            return Msg;
        }

        public void SaveRoleActions(int roleId, int menuId, string actionIds) {
            using (DbTrans trans = DB.BeginTrans()) {
                try {
                    IList<T_Action> actionList = trans.From<T_Action>().Where(T_Action._.MenuID == menuId).ToList();

                    if (actionList.Count > 0) {
                        trans.Delete<T_RoleAction>(T_RoleAction._.RoleID == roleId && T_RoleAction._.ActionID.In(actionList.Select(m => m.ActionID).ToArray()));
                    }
                    string[] actionIdArray = actionIds.Split(',');
                    DbBatch batch = trans.BeginBatch(actionIdArray.Length);
                    foreach (var actionId in actionIdArray) {
                        if (string.IsNullOrEmpty(actionId)) continue;
                        T_RoleAction roleAction = new T_RoleAction();
                        roleAction.ActionID = Convert.ToInt32(actionId);
                        roleAction.RoleID = roleId;
                        roleAction.Detach();
                        batch.Save(roleAction);
                    }
                    batch.Process();
                    trans.Commit();
                }
                catch (Exception) {
                    trans.Rollback();
                    throw;
                }
            }
        }
    }
}
